' DOSDoors
' See changelog.txt or the commit log for updates as they're made.

CONST VER_MAJOR   = 0
CONST VER_MINOR   = 0
CONST VER_BUILD   = 11

#Print Main.bas

#include once "main.bi"
#include once "video.bi"
#include once "vars.bi"
#include once "interp.bi"

Sub LogString(strText As String)
    Dim As Integer  LogFreeFile
    Dim As String   LineToWrite
    
    LogFreeFile = FreeFile
    
    Open "./debuglog.txt" For Append As #LogFreeFile
        Print #LogFreeFile, Time() & ": " & strText
    Close #LogFreeFile
End Sub

#ifdef DEBUG_LOG
    LogString ("Init")
#endif

Const video_width       = 800
Const video_height      = 600
Const video_bpp         = 32

Dim As String   keycode, StartTime
Dim As Integer  Frames, ReturnCode
Dim As ULongInt uptime, screensaverTime
Dim As Byte     screensaverRunning = 0

StartTime = Time

' Set up the color scheme
ColorScheme.Door_Face           = RGB(255, 255, 255)
ColorScheme.Door_Text           = RGB(0, 0, 0)
ColorScheme.Door_Highlight      = RGB(33, 115, 217)
ColorScheme.Door_Shadow         = RGB(33, 115, 217)
ColorScheme.Door_CaptionBar     = RGB(33, 115, 217)
ColorScheme.Door_CaptionText    = RGB(255, 255, 255)
ColorScheme.Button_Face         = RGB(66, 124, 247)
ColorScheme.Button_HighlightIn  = RGB(66, 124, 247)
ColorScheme.Button_ShadowIn     = RGB(66, 124, 247)
ColorScheme.Button_HighlightOut = RGB(225, 236, 251)
ColorScheme.Button_ShadowOut    = RGB(225, 236, 251)
ColorScheme.Button_Text         = RGB(255, 255, 255)
ColorScheme.Button_TextDisabled = RGB(132, 132, 132)
ColorScheme.Button_TextDisabledShadow = RGB(66, 124, 247)

' Set up some system variables
' Note: To optimize this, put the most-updated variables at the top
AddVariable("System.OS.Mouse.X", "integer", "0")
AddVariable("System.OS.Mouse.Y", "integer", "0")
AddVariable("System.OS.Display.FPS", "integer", "0")
AddVariable("System.OS.CPS", "integer", "0")
AddVariable("System.OS.Uptime", "integer", "0")
AddVariable("System.OS.Mouse.Button.Left", "integer", "0")
AddVariable("System.OS.Mouse.Button.Right", "integer", "0")
AddVariable("System.OS.TotalRunningPrograms", "integer", "0")
AddVariable("System.OS.Display.Windows.Active", "integer", "0")
AddVariable("System.OS.Display.Windows.Active.Name", "string", "UNDEFINED")
AddVariable("System.OS.Display.Width", "integer", "0")
AddVariable("System.OS.Display.Height", "integer", "0")
AddVariable("System.OS.Display.BitsPerPixel", "integer", "0")
AddVariable("System.OS.Display.Windows.Count", "integer", "0")
AddVariable("System.OS.Display.Windows.Memory", "integer", "0")
AddVariable("System.OS.Security.User.Username", "string", "testuser")
AddVariable("System.OS.Security.User.Name", "string", "Test User")
AddVariable("System.OS.Version.Major", "integer", Str(VER_MAJOR))
AddVariable("System.OS.Version.Minor", "integer", Str(VER_MINOR))
AddVariable("System.OS.Version.Build", "integer", Str(VER_BUILD))

' Assign all the default colors
AssignColorsToVariables()

' Attempt to switch to the requested screen resolution
SwitchResolution(video_width, video_height, video_bpp)

UpdateScreen = 0

Dim tempInt As Integer

' Setup the main shell program (NOT IMPLEMENTED YET)
' tempInt = CreateProgram("Shell")

' Setup the desktop background
Dim desktop As Any Ptr

tempInt = CreateWindow("Desktop", 1280, 1024)   ' Max size
desktop = GetWindowBuffer("Desktop")

' Paint the wallpaper
Line desktop, (0, 0) - (video_width, video_height), RGB (0, 128, 128), BF
BLoad "./images/cupcake.bmp", desktop

' Draw the version information onto the wallpaper itself
DrawText3D (desktop, 2, 20, "DOS Doors (Version: " & GetVariable("System.OS.Version.Major") & "." & GetVariable("System.OS.Version.Minor") & " build 00" & GetVariable("System.OS.Version.Build") & ")")

UpdateScreen = 1

Randomize , 3

Dim As UInteger tempProgram
tempProgram = LoadProgram("./apps/shell.des")

Dim As Integer  mouseX, mouseY, mouseButtons, oldmouseX, oldmouseY
Dim As Integer  x, y, z
Dim As String   stringX
Dim As Integer  intLoop, intLoop2
Dim As Integer  intClickingControl
Dim As Double   TimerNow
#ifdef DEBUG_LOG
    LogString("Init:End")
#endif

Do
    Frames = Frames + 1

    ' Update the mouse variables
    ReturnCode = GetMouse(mouseX, mouseY, , mouseButtons)
    ReturnCode = SetVariable("System.OS.Mouse.X", Str(mouseX))
    ReturnCode = SetVariable("System.OS.Mouse.Y", Str(mouseY))
    ReturnCode = SetVariable("System.OS.Mouse.Button.Left", Str(IIf((mouseButtons And 1), 1, 0)))
    ReturnCode = SetVariable("System.OS.Mouse.Button.Right", Str(IIf((mouseButtons And 2), 1, 0)))

    If (oldmouseX <> mouseX) OR (oldmouseY <> mouseY) Then
        oldmouseX = mouseX
        oldmouseY = mouseY
        screensaverTime = 0
        screensaverRunning = 0
    End If

    ' Things to do once a second
    If Time <> StartTime Then
        ' Update uptime
        StartTime = Time
        uptime = uptime + 1
        screensaverTime = screensaverTime + 1

        ' Run the screensaver if it hits five minutes
        If screensaverTime >= 300 Then
            screensaverTime = 300
            If screensaverRunning = 0 Then
                screensaverRunning = 1
                tempProgram = LoadProgram("./apps/scrnsvr.des")
            End If
        End If

        ReturnCode = SetVariable("System.OS.Uptime", Str(uptime))

        ' Update FPS counter variable
        ReturnCode = SetVariable("System.OS.Display.FPS", Str(Frames))

        ' Update Commands Per Second counter variable
        ReturnCode = SetVariable("System.OS.CPS", Str(CPS))

        ' Reset CPS counter
        CPS = 0

        ' Update window counter variable
        ReturnCode = SetVariable("System.OS.Display.Windows.Count", Str(TotalWindows))

        ' Update window memory usage variable
        ReturnCode = SetVariable("System.OS.Display.Windows.Memory", Str(GetWindowBufferTotalSize()))

        ' Update the number of total running programs
        ReturnCode = SetVariable("System.OS.TotalRunningPrograms", Str(TotalPrograms + 1))

        ' Reset FPS counter
        Frames = 0
    End If

    ' Test for window dragging
    If (DraggingWindow = 1) Then
        If (mouseButtons And 1) Then
            'ReturnCode = TestDragging (mouseX, mouseY)
            x = Window_X2(Dragging_Num) - Window_X1(Dragging_Num)
            y = Window_Y2(Dragging_Num) - Window_Y1(Dragging_Num)
                  
            Window_X1(Dragging_Num) = mouseX - Dragging_StartX
            Window_X2(Dragging_Num) = Window_X1(Dragging_Num) + x

            Window_Y1(Dragging_Num) = mouseY - Dragging_StartY
            Window_Y2(Dragging_Num) = Window_Y1(Dragging_Num) + y
            Window_Redraw(Dragging_Num) = 1
            UpdateScreen = 1
        Else
            DraggingWindow = 0
            Window_Redraw(Dragging_Num) = 1
            UpdateScreen = 1
        End If
    Else    ' See if the user is clicking on a control
        If (Not mouseButtons And 1) And (intClickingControl > 0) Then
            Select Case Window_Controls(intClickingControl).Type
                Case 1  ' Command Button
                    Window_Controls(intClickingControl).Value = 0
                Case 2  ' Checkbox
                    'If (Window_Controls(intClickingControl).Value = 1) Then
                    '      Window_Controls(intClickingControl).Value = 0
                    'Else
                    '      Window_Controls(intClickingControl).Value = 1
                    'End If
            End Select
            RedrawControls(Window_Controls(intClickingControl).Parent)
            intClickingControl = 0
        End If

        If (mouseButtons And 1) Then
            ' Bring a window to the front of the Z-Order if clicked
            ReturnCode = TestInsideDoor(mouseX, mouseY)
            If ReturnCode > 0 Then
                SetZOrderTop (ReturnCode)
            End If
                  
            ' Test to see if user is clicking on a control
            ReturnCode = TestControlClicked(mouseX, mouseY)

            If (ReturnCode > 0) Then
                If (intClickingControl = 0) Then
                    Select Case Window_Controls(ReturnCode).Type
                        Case 1      ' Command Button
                            Window_Controls(ReturnCode).Value = 1
                            
                            ' Jump to "cmdButton_Click()"
                            Program_Location(Window_Controls(ReturnCode).ProgramOwner) = GetJumpTable(Window_Controls(ReturnCode).ProgramOwner, Window_Controls(ReturnCode).Name & "_Click()")
                        Case 2      ' Checkbox
                            If (Window_Controls(ReturnCode).Value = 1) Then
                                Window_Controls(ReturnCode).Value = 0
                                ' Jump to "optButton_Unchecked()"
                                Program_Location(Window_Controls(ReturnCode).ProgramOwner) = GetJumpTable(Window_Controls(ReturnCode).ProgramOwner, Window_Controls(ReturnCode).Name & "_Uncheck()")
                            Else
                                Window_Controls(ReturnCode).Value = 1
                                ' Jump to "optButton_Checked()"
                                Program_Location(Window_Controls(ReturnCode).ProgramOwner) = GetJumpTable(Window_Controls(ReturnCode).ProgramOwner, Window_Controls(ReturnCode).Name & "_Check()")
                            End If
                    End Select
                    intClickingControl = ReturnCode
                    RedrawControls(Window_Controls(ReturnCode).Parent)
                End If
            Else
        End If

            ' Test for dragging of the windows
            ReturnCode = TestDragging(mouseX, mouseY)
        End If
    End If

    ' Check Timers and update program location accordingly
    TimerNow = Timer
    If TotalTimers > 0 Then
        For intLoop = 1 To TotalTimers
            If Timer_Enabled(intLoop) = 1 Then
                If (TimerNow >= Timer_NextInterval(intLoop)) Then
                    Program_Location(Timer_Program(intLoop)) = GetJumpTable(Timer_Program(intLoop), Timer_JumpLocation(intLoop))
                    Timer_NextInterval(intLoop) = Timer + (Timer_Interval(intLoop) / 1000)
                End If
            End If
        Next    ' intLoop
    End If

    ' Run each of the programs
    For intLoop = 0 To TotalPrograms
        RunProgram(intLoop)
    Next  ' intLoop

    RedrawDoors()

    ' Update the entire screen
    If UpdateScreen = 1 Then
        RedrawScreen()
        UpdateScreen = 0
    End If

    ' Keyboard handler
    keycode = Inkey()
    If Len(keycode) > 0 Then
        screenSaverTime = 0
        screensaverRunning = 0
        If keycode = Chr(27) Then                 ' Escape
            ' KernelPanic "Kill key requested!"
            KernelPanicQR 2
        ElseIf keycode = Chr(42) Then             ' PrintScreen
            ' Take a screenshot - doesn't seem to work on Windows Builds
            BSave "./ss/ss.bmp", 0
        ElseIf ASC(keycode, 1) = 255 Then
            If ASC(keycode, 2) = 59 Then        ' F1
                SwitchResolution (640, 480, 32)
            ElseIf ASC(keycode, 2) = 60 Then    ' F2
                SwitchResolution (800, 600, 32)
            ElseIf ASC(keycode, 2) = 61 Then    ' F3
                SwitchResolution (1024, 768, 32)
            ElseIf ASC(keycode, 2) = 62 Then    ' F4
                SwitchResolution (1280, 1024, 32)
            'ElseIf ASC(keycode, 2) = 28 Then    ' ALT + Enter
                ' Do something to go fullscreen here...
            End If
        Else  ' Anything else, throw into the active windows' KB buffer
            Window_KBQueue(Window_ZOrder(1)) = Window_KBQueue(Window_ZOrder(1)) & keycode
        End If
    End If    
Loop